package www.cskaoyan.com.utils;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 请求分发器: 根据请求的url, 分发请求
 */
public class Dispatcher {

    private static final String PATH = "out/production/java-gui/www/cskaoyan/com/controller"; // 编译文件路径
    private static final String PACKAGEPATH = "www.cskaoyan.com.controller."; // 包路径

    private HashMap<String, Object> map; // 用来存储反射的Controller类

    public Dispatcher(){
        map = new HashMap<>();
        try {
            initController();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化分发器: 获得所有Controller类
     */
    private void initController() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        File file = new File(PATH);
        File[] files = file.listFiles();

        // 获取所有要类的名字
        ArrayList<String> list = new ArrayList<>();
        for (File fileName : files) {
            String name = fileName.getName();
            String controllerName = name.substring(0, name.indexOf("."));
            list.add(controllerName);
        }

        // list示例: [LoginController, UserController]
        // 获取所有要类存储到Map中: (结构)  类名 = 类
        for (String className : list) {
            String reflectPath = PACKAGEPATH + className;
            Class cls = Class.forName(reflectPath);
            map.put(className, cls);
        }
    }


    /**
     * 分发请求
     * @param request: 请求信息
     * @return: 分发请求之后获得的结果
     */
    public Response dispatch(Request request) throws InvocationTargetException, IllegalAccessException, InstantiationException {

        // 获得url的两级结构(eg: Login/login),
        // 第一级代表Colltroller类名
        // 第二级代表该类中的方法
        String url = request.getUrl();
        if (url.indexOf('/') == -1){
            // 代表不是耳机路径写法
            return new Response(400, "请书写正确请求接口", false);
        }
        String[] split = url.split("/");


        // 在Map(存储所有: Colltroller类名=Colltroller类  的map结构 )中获取对应Colltroller类
        Class cls = (Class) map.get(split[0]+"Controller");

        // 不存在对应请求接口: 404
        if (cls == null){
            return new Response(404, "请求接口类不存在", false);
        }

        // 获得请求的Colltroller类下的所有方法
        Method[] methods = cls.getMethods();
        for (Method method : methods) {
            String name = method.getName();
            //  找到请求的方法
            if (name.equals(split[1])){
                // 调用对应的controller方法
                Object invoke = method.invoke(cls.newInstance(), request);
                return (Response) invoke;
            }
        }

        return new Response(404, "请求类存在,接口不存在", false);
    }
}
